6
תגובות

שימוש במספר מחלקות + mysqli

פתח mmh19 ,
שלום,
כאשר משתמשים במספר מחלקות שבהן יש שאילתות,
איך הכי כדאי לעבוד עם אובייקט של mysqli?

אני חשבתי על כמה אפשרויות:
1) שימוש בglobal בכל מחלקה של האובייקט mysqli הגלובלי.
2) יצירת מחלקה בשם main שתכיל רק משתנה סטטי בשם $mysqli ופשוט לרשת ממנה בכל המחלקות שבאתר.
3) שליחת האובייקט $mysqli (by ref) בכל יצירת אובייקט של כל מחלקה.

מה הכי נכון לעשות?

תודה.

6 תשובות

avatar ענה zacharya ב 30 לאוקטובר 2013 #

אין דרך נכונה (אם כי תגובה של אלכס על שאלה שלי "באתר יש כתבות על כל מיני דברים שצריך בכל דרך אפשרית להימנע מהם, כמו @, die
וglobal זה אחד מהם. להימנע מזה אפשר די בקלות, על ידי העברת פרמטרים. "), ככה שאני עשיתי כמו הרעיון של אלכס, יצרתי משתנה בדף האינדקס ושם כל מחלקה שאני מפעיל העברתי לה את המשתנה של הmysqli ובעזרת __construct הפכתי אותו למשתנה של המחלקה ככה שאוכל להשתמש בו כך:

$this->con;


הנה התגובה של אלכס:
http://phpguide.co.il/q1611/%D7%A7%D7%A8%D7%99%D7%90%D7%94+%D7%9C%D7%9E%D7%97%D7%9C%D7%A7%D7%94+%D7%91%D7%AA%D7%95%D7%9A+%D7%9E%D7%97%D7%9C%D7%A7%D7%94.htm#answer_7359

avatar ענה mmh19 ב 30 לאוקטובר 2013 #

ישנה גם האפשרות הבאה:

function getDb()
{
  global $config;
  static $mysqli;
 
  if(empty($config))
    die('Error: $config not set yet!');
 
  if (!$mysqli)
  {
    $mysqli = new db
    (
      $config['database']['host'],
      $config['database']['username'],
      $config['database']['password'],
      $config['database']['name'],
      $config['database']['charset']
    );
  }
  return $mysqli;
}

לקרוא לפונקציה הגלובאלית הזאת בכל קונסטרקטור של מחלקה.

avatar ענה zacharya ב 31 לאוקטובר 2013 #

גם אפשרות, רק שים לב שאתה משתמש בglobal וdie למרות שזה לא טוב.

avatar ענה mmh19 ב 31 לאוקטובר 2013 #

@zacharya
אתה מקובע על משהו כללי מידי,
global וdie לא בעיתיות בפני עצמן, אלא הן פשוט רגישות בשימוש שלהן וצריך לשים לב טוב טוב מה עושים,
במקרה הזה יש את המשתנה הגלובאלי config שאם הוא לא מוגדר אז גם שום דבר באתר לא יעבוד ככה שזה לא בעיתי..
וכנ"ל הdie הוא בודק שהconfig אכן קיים אחרת מפסיק את הקוד עם הודעת שגיאה בהתאם, כי אם אין קונפיג שום דבר באתר לא יעבוד...

avatar ענה intval ב 01 לנובמבר 2013 #

global, static & die הם לא סתם בעייתיים, אלה סופר בעיתיים בפני עצמם או ביחד עם דברים אחרים.
אין שום סיבה להשתמש בהם וזו דרך מאוד רעה לבדוק או להודיע למשתמש על שגיאות.

לא צריך להיות שום משתנה גלובאלי קונפיג. כל מחלקה שצריכה את המשתנה קונפיג, צריכה לקבל אותו בתור פרמטר ובפועל יש מחלקה אחת כזאת בלבד. נראה הגיוני לעשות משתנה גלובאלי שרק מחלקה אחת משתמשת בו?

זכריה צירף קישור לשאלה זהה והתושבה נשארת אותו דבר. כל התלויות של מחלקה חייבות להיות מועברות בתור פרמטרים. בין אם התלות הזאת היא מחלקה אחרת, או בין עם זה קונפיג.

כל זה נראה בסופו של יום ככה:

class SqlAdapter implements IDbAdapter
{
  public function __construct($host, $user, $pass, $dbname)
  {
  }

  public function Query($query)
  {
    try
    {
      if(!$this->connected)
        $this->connect();
       
      // don't connect in constructor
      // As I wrote in the book, having side effects in constructor
      // is a very bad thing
     
      return $this->execute($query);   
    }..
  }
}


class Authenticator
{
  public function __construct(IUserDal $dal)
  {
    $this->dal = $dal;
  }

  public function Auth($login, $pass)
  {
    return $this->dal->CountUsersByLoginAndPass($login, $pass) === 1;
  }
}

class UserDal implements IUserDal
{
  public function __construct(IDbAdapter $db)
  {
    $this->db = $db;
  }

  public function CountUsersByLoginAndPass($login, $pass)
  {
    $this->db->Query("Select Count(*) ");
    ...
  }

  // all other database user related stuff.
  // only one class actually holds queries.
  // other classes hold references to respective DadaAccessLayer classes (DAL)
  public function UpdateLastUsersVisitTime() { .. }
  public function GetUserInfo($id){ .. }
  public function SaveUserInfo($user) { .. }
}

avatar ענה OrelBeY ב 01 לנובמבר 2013 #

@intval סטטיות היא נושא בפני עצמו, שלא הצלחתי להבין מה הבעיה בו. אני מציע להעביר את זה לדיון אחר.